package com.service.abolishing.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.service.abolishing.dto.ApDetailDto;
import com.service.abolishing.dto.DeviceDto;
import com.service.abolishing.entity.ApDetail;
import com.service.abolishing.entity.CloudCampusInfo;
import com.service.config.constant.ApiUrlConstants;
import com.service.config.dto.SiteDto;
import com.service.config.dto.TerminalUserDto;
import com.service.config.utils.JsonXMLUtils;
import com.service.config.utils.ModelMapperUtil;
import com.service.config.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import static com.service.config.utils.UuIDUtil.randomNum;

/**
 * @program: CloudCampusService
 * @description: 云管理Api封装
 * @author: rui
 * @create: 2021-03-31 14:26
 **/

@Component
@Slf4j
public class CloudCampusApi implements ApiUrlConstants {
    private final ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("thread-call-runner-%d").build();
    private final ExecutorService product = new ThreadPoolExecutor(10,20,200L, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<Runnable>(),namedThreadFactory);
    @Resource
    RestTemplate restTemplate;
    int pageSize = 100;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 获取token
     *
     * @param username
     * @param password
     * @param requestHeaders
     * @return
     */
    public String getToken(String username, String password, HttpHeaders requestHeaders, String domain) {
        //获取token
        Map map = new HashMap();
        map.put("userName", username);
        map.put("password", password);
        try {
            HttpEntity<Map> requestEntity = new HttpEntity<Map>(map, requestHeaders);
            ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + CLOUD_CAMPUS_TOKEN_URL, HttpMethod.POST, requestEntity, JSONObject.class);
            return response.getBody().getJSONObject("data").getString("token_id");
        } catch (Exception e) {
            log.error("debug Token ==>" + e.getMessage());
            return null;
        }
    }


    /**
     * 获取站点site
     *
     * @param requestHeaders
     * @param cloudCampusInfo
     * @return
     */
    public List<SiteDto> getSites(HttpHeaders requestHeaders, CloudCampusInfo cloudCampusInfo) {
        //获取站点
        boolean flag = true;
        int pageIndex = 1;
        List<SiteDto> siteDtos = new ArrayList<>();
        try {
            while (flag) {
                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
                ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + cloudCampusInfo.getDomain() + SITE_URL + pageIndex, HttpMethod.GET, requestEntity, JSONObject.class);
                JSONArray data = Objects.requireNonNull(response.getBody()).getJSONArray("data");
                if (!data.isEmpty()) {
                    siteDtos.addAll(data.toJavaList(SiteDto.class));
                    pageIndex++;
                } else {
                    flag = false;
                }
            }
            return siteDtos;
        } catch (Exception e) {
            log.error("debug getSites ==>" + e.getMessage());
            return null;
        }
    }


    /**
     * 站点下终端用户列表获取
     *
     *
     * @param status  online---在线、offline---离线
     * @param sites
     * @param requestHeaders
     * @return
     */
    public Map getTerminalUserList(String status, List<SiteDto> sites, HttpHeaders requestHeaders, String domain) {
        List<TerminalUserDto> list = new ArrayList<>();
        Map map = new HashMap();
        sites.forEach(site -> {
            AtomicBoolean flag = new AtomicBoolean(true);
            AtomicInteger pageIndex = new AtomicInteger(1);
            while (flag.get()) {
                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
                ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + TERMINAL_USER_LIST + site.getId() + "?status="+status+"&pageSize=100&pageIndex=" + pageIndex, HttpMethod.GET, requestEntity, JSONObject.class);
                JSONArray data = response.getBody().getJSONArray("data");
                if (!data.isEmpty()) {
                    List<TerminalUserDto> list1 = data.toJavaList(TerminalUserDto.class);
                    list1.forEach(terminalUserDto -> {
                        terminalUserDto.setSiteId(site.getId());
                        terminalUserDto.setSiteName(site.getName());
                    });
                    list.addAll(list1);
                    pageIndex.getAndIncrement();
                    flag.set(false);
                } else {
                    flag.set(false);
                }
            }
        });
        map.put("TerminalUserDto",list);
        return map;
    }
    /**
     * 站点下终端用户列表获取
     *
     *
     * @param status  online---在线、offline---离线
     * @param sites
     * @param requestHeaders
     * @return
     */
    public Map getTerminalUserList(String status, SiteDto sites, HttpHeaders requestHeaders, String domain) {
        List<TerminalUserDto> list = new ArrayList<>();
        Map map = new HashMap();
        AtomicBoolean flag = new AtomicBoolean(true);
        AtomicInteger pageIndex = new AtomicInteger(1);
        while (flag.get()) {
            HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
            ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + TERMINAL_USER_LIST + sites.getId() + "?status="+status+"&pageSize=100&pageIndex=" + pageIndex, HttpMethod.GET, requestEntity, JSONObject.class);
            JSONArray data = Objects.requireNonNull(response.getBody()).getJSONArray("data");
            if (!data.isEmpty()) {
                List<TerminalUserDto> list1 = data.toJavaList(TerminalUserDto.class);
                list1.forEach(terminalUserDto -> {
                    terminalUserDto.setSiteId(sites.getId());
                    terminalUserDto.setSiteName(sites.getName());
                });
                list.addAll(list1);
                pageIndex.getAndIncrement();
            }
            flag.set(false);
        }
        map.put("TerminalUserDto",list);
        return map;
    }
    /**
     * 设备维度下用户信息
     * @param status  online---在线、offline---离线
     * @param apDetails
     * @param requestHeaders
     * @param domain
     * @return
     */
    public Map getByDeviceTerminalUserList(String status, ApDetail apDetails, HttpHeaders requestHeaders, String domain,String timeStamp) {
        List<TerminalUserDto> list = new ArrayList<>();
        Map map = new HashMap();
        product.submit(()->{
            AtomicInteger pageIndex = new AtomicInteger(1);
            HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
            ResponseEntity<JSONObject> response = restTemplate.exchange(URL_FIRST + domain + DEVICE_USER_INFO + apDetails.getDeviceId() + "?status="+status+
                    "&pageSize=" + pageSize + "&pageIndex=" + pageIndex, HttpMethod.GET, requestEntity, JSONObject.class);
            Integer total1 = Objects.requireNonNull(response.getBody()).getInteger("total");
            ApDetailDto apDetailDto = ModelMapperUtil.strictMap(apDetails, ApDetailDto.class);
            apDetailDto.setCount(randomNum(20,100));
            try {
                redisUtil.zAdd(apDetails.getDeviceId()+":"+apDetails.getManageInfoId(), JsonXMLUtils.obj2json(apDetailDto),Integer.parseInt(timeStamp));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        map.put("TerminalUserDto",list);
        return map;
    }
    /**
     * 获取设备列表信息
     *
     * @param sites
     * @param requestHeaders
     * @param
     * @return
     */
    public List<DeviceDto> getDevices(List<SiteDto> sites, HttpHeaders requestHeaders, String domain) {
        //查询设备(默认查询站点下所有设备)
        List<DeviceDto> deviceDtos = new ArrayList<>();
        try {
            sites.forEach(site -> {
                AtomicBoolean flag = new AtomicBoolean(true);
                AtomicInteger pageIndex = new AtomicInteger(1);
                String siteId = site.getId();
                while (flag.get()) {
                    HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
                    ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + domain + DEVICES_URL + "?pageSize=100&pageIndex=" + pageIndex + "&siteId=" + siteId, HttpMethod.GET, requestEntity, JSONObject.class);
                    JSONArray data = Objects.requireNonNull(response.getBody()).getJSONArray("data");
                    if (!data.isEmpty()) {
                        deviceDtos.addAll(data.toJavaList(DeviceDto.class));
                        pageIndex.getAndIncrement();
                    } else {
                        flag.set(false);
                    }}
            });
            return deviceDtos;
        } catch (Exception e) {
            log.error("debug getDevices ==>" + e.getMessage());
            return null;
        }
    }

    /**
     * 获取设备列表信息
     * @param cloudCampusInfo
     * @param requestHeaders
     * @param
     * @return
     */
    public List<DeviceDto> getDevices(HttpHeaders requestHeaders, CloudCampusInfo cloudCampusInfo) {
        //查询设备(默认查询站点下所有设备)
        List<DeviceDto> deviceDtos = new ArrayList<>();
        try {
            AtomicBoolean flag = new AtomicBoolean(true);
            AtomicInteger pageIndex = new AtomicInteger(1);
            while (flag.get()) {
                HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
                ResponseEntity<JSONObject> response = restTemplate.exchange("https://" + cloudCampusInfo.getDomain() + DEVICES_URL + "?pageSize=100&pageIndex=" + pageIndex, HttpMethod.GET, requestEntity, JSONObject.class);
                JSONArray data = Objects.requireNonNull(response.getBody()).getJSONArray("data");
                if (!data.isEmpty()) {
                    deviceDtos.addAll(data.toJavaList(DeviceDto.class));
                    pageIndex.getAndIncrement();
                } else {
                    flag.set(false);
                }}

            return deviceDtos;
        } catch (Exception e) {
            log.error("debug getDevices ==>" + e.getMessage());
            return null;
        }
    }
}